package com.vmix.android.vmixsdk.util.http;

/**
 * @author Jeff Smits (jeffs@vmix.com)
 */

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.scheme.SocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.vmix.android.vmixsdk.util.http.IHttpApi;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class VmixAbstractHttpAPI implements IHttpApi{

	private static final String DEFAULT_CLIENT_VERSION = "com.vmix.vmixmobiledemo";
	private static final String CLIENT_VERSION_HEADER = "User-Agent";
	private static final int TIMEOUT = 60;
    private final DefaultHttpClient vHttpClient;
    private final String vClientVersion;
	
    public VmixAbstractHttpAPI(DefaultHttpClient httpClient, String clientVersion) {
        this.vHttpClient = httpClient;
        if (clientVersion != null) {
            this.vClientVersion = clientVersion;
        } else {
            this.vClientVersion = DEFAULT_CLIENT_VERSION;
        }
    }
    public HttpResponse executeHttpRequest(HttpRequestBase httpRequest) throws IOException {

        try {
            this.vHttpClient.getConnectionManager().closeExpiredConnections();
            return this.vHttpClient.execute(httpRequest);
        } catch (IOException e) {
            httpRequest.abort();
            throw e;
        }
    }
	
	public HttpGet buildHttpGet( String url, NameValuePair... nameValuePairs ){

        String query = URLEncodedUtils.format(stripNulls(nameValuePairs), HTTP.UTF_8);
        HttpGet httpGet = new HttpGet(url + "?" + query);
        httpGet.addHeader(CLIENT_VERSION_HEADER, this.vClientVersion);

        return httpGet;
	}
	

	public HttpPost buildHttpPost (String url, NameValuePair... nameValuePairs ){
		
	        HttpPost httpPost = new HttpPost(url);
	        httpPost.addHeader(CLIENT_VERSION_HEADER, this.vClientVersion);
	        try {
	            httpPost.setEntity(new UrlEncodedFormEntity(stripNulls(nameValuePairs), HTTP.UTF_8));
	        } catch (UnsupportedEncodingException e1) {
	            throw new IllegalArgumentException("Unable to encode http parameters.");
	        }
	        return httpPost;
		
	}
	
    public HttpURLConnection createHttpURLConnectionPost(URL url, String boundary) throws IOException {
    	HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
    	conn.setDoInput(true);        
    	conn.setDoOutput(true); 
    	conn.setUseCaches(false); 
    	conn.setConnectTimeout(TIMEOUT * 1000);
    	conn.setRequestMethod("POST");
    	conn.setRequestProperty(CLIENT_VERSION_HEADER, this.vClientVersion);
    	conn.setRequestProperty("Connection", "Keep-Alive"); 
    	conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
    
    	return conn;
    }
    
    public static final DefaultHttpClient createHttpClient() {

        final SchemeRegistry supportedSchemes = new SchemeRegistry();


        final SocketFactory sf = PlainSocketFactory.getSocketFactory();
        supportedSchemes.register(new Scheme("http", sf, 80));


        final HttpParams httpParams = createHttpParams();
        HttpClientParams.setRedirecting(httpParams, false);

        final ClientConnectionManager ccm = new ThreadSafeClientConnManager(httpParams,
                supportedSchemes);
        return new DefaultHttpClient(ccm, httpParams);
    }
    
    private static final HttpParams createHttpParams() {
        final HttpParams params = new BasicHttpParams();
        HttpConnectionParams.setStaleCheckingEnabled(params, false);

        HttpConnectionParams.setConnectionTimeout(params, TIMEOUT * 1000);
        HttpConnectionParams.setSoTimeout(params, TIMEOUT * 1000);
        HttpConnectionParams.setSocketBufferSize(params, 8192);

        return params;
    }
	
	 private List<NameValuePair> stripNulls(NameValuePair... nameValuePairs) {
	        List<NameValuePair> params = new ArrayList<NameValuePair>();
	        for (int i = 0; i < nameValuePairs.length; i++) {
	            NameValuePair param = nameValuePairs[i];
	            if (param.getValue() != null) {
	                params.add(param);
	            }
	        }
	        return params;
	    }
}
